﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using FastReport;
using FastReport.Export;
using FastReport.Export.Pdf;
using FastReport.Export.OoXML;
using FastReport.Preview;
using Tzx.Utilities;
using FastReport.Export.Image;

namespace Tzx.Tools.Payroll2Images.Exe.TableToReport
{
    /// <summary>
    /// 表格数据,报表模板,加载到报表组件
    /// </summary>
    public partial class UcOneRowToReport : UserControl
    {

        /// <summary>
        /// 构造
        /// </summary>
        public UcOneRowToReport()
        {
            InitializeComponent();

            InitPreview();//报表预览控件

            LblReadText.Text = "预览和导出图片文件";

            //下一步,触发事件
            BtnNext.Click += delegate(object sender, EventArgs e)
            {
                EventHandler handler = NextClick;
                if (handler != null) { handler(this, EventArgs.Empty); }
            };
        }

        /// <summary>
        /// Message标题
        /// </summary>
        private string Title
        {
            get
            {
                if (Parent != null)
                {
                    return Parent.Text;
                }
                return string.Empty;
            }
        }

        #region report

        /// <summary>
        /// 报表
        /// </summary>
        private Report m_report;// = new Report();//创建报表对象

        /// <summary>
        /// 报表预览控件
        /// </summary>
        private PreviewControl m_report_view;

        /// <summary>
        /// 初始化报表预览控件
        /// </summary>
        private void InitPreview()
        {
            m_report_view = new PreviewControl();

            //放入Panel
            int count = panelFull.Controls.Count;
            for (int i = count - 1; i >= 0; i--)
            {
                panelFull.Controls.RemoveAt(i);
            }

            // 将报表预览控件添加到窗体中
            panelFull.Controls.Add(m_report_view);//控件
            m_report_view.Parent = panelFull;//控件
            m_report_view.Dock = DockStyle.Fill;
            m_report_view.ToolbarVisible = false;
        }

        /// <summary>
        /// 初始化报表组件(一般在重新赋值数据后)
        /// </summary>
        private void InitReport()
        {
            m_report = new Report();

            //语言包
            string lng_file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FastReport_chs.frl");
            if (File.Exists(lng_file))
            {
                FastReport.Utils.Res.LoadLocale(lng_file.ToUpper());
            }
        }

        #endregion

        #region fill,报表frx,人员name

        /// <summary>
        /// 本应用程序目录有几个frx文件
        /// </summary>
        private void Fill_Frx()
        {
            CbReportFiles.Items.Clear();
            CbReportFiles.Items.Add("选择报表模板");

            //
            string dir = string.Format("{0}", AppDomain.CurrentDomain.BaseDirectory);
            string[] frx_ss = Directory.GetFiles(dir, "*.frx");
            foreach (string frx in frx_ss)
            {
                string file_name = Path.GetFileName(frx);
                if (string.IsNullOrEmpty(file_name))
                {
                    continue;
                }
                int idx = CbReportFiles.Items.Add(file_name);
            }

            //选中哪一个作为默认
        }

        /// <summary>
        /// 数据列表
        /// </summary>
        private void Fill_EmployeeName()
        {
            //DataTable table
            if (m_table == null)
            {
                MessageBox.Show("没有数据", Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //
            DataTable tbl = m_table.Copy();//为了防止两个控件绑定同一个数据集
            LbDataRow.DataSource = tbl;
            LbDataRow.ValueMember = App.ColumnFixName_FID;
            LbDataRow.DisplayMember = App.ColumnFixName_FEmployeeAllName;
        }

        /// <summary>
        /// 当前选择报表文件完整路径和名称
        /// </summary>
        private bool GetFrxFileFullPathName(out string frx_fullpathname, out string message)
        {
            //
            frx_fullpathname = null;
            message = null;

            //
            string frx_filename = string.Format("{0}", (string)CbReportFiles.SelectedItem);
            if (frx_filename.Length == 0)
            {
                message = "没有选择报表模板";
                return false;
            }

            frx_fullpathname = Path.Combine(string.Format("{0}", AppDomain.CurrentDomain.BaseDirectory), frx_filename);
            if (!File.Exists(frx_fullpathname))
            {
                message = "报表模板文件不存在";
                return false;
            }

            //
            return true;
        }

        #endregion

        #region public 赋值数据表,返回输出文件夹路径

        #region 1.SetData外部赋值

        /// <summary>
        /// 1.外部赋值使用
        /// </summary>
        /// <param name="table"></param>
        public void SetData(DataTable table)
        {
            m_table = table; //赋值
            m_table_clone_one = null; //清空用于判断重新克隆结构

            InitTable();//检查报表是否存在必需的名称字段
            InitReport();//初始化报表组件

            Fill_Frx();//填充报表rpt文件

            //开始填充人员name列表
            LbDataRow.SelectedIndexChanged -= LbDataRow_SelectedIndexChanged;
            Fill_EmployeeName();//数据列表m_table
            LbDataRow.SelectedIndexChanged += LbDataRow_SelectedIndexChanged;
        }

        /// <summary>
        /// 外部传入数据表
        /// </summary>
        private DataTable m_table;

        /// <summary>
        /// 克隆一行数据,用于预览和导出一行
        /// </summary>
        private DataTable m_table_clone_one = null;

        /// <summary>
        /// 检查导入Excel表是否有唯一行ID列,和接收人名称字符列
        /// </summary>
        private void InitTable()
        {
            DataTable excelTable = m_table;
            if (excelTable == null)
            {
                return;
            }

            //添加字段1:表必需要有一个唯一行字段
            if (!excelTable.Columns.Contains(App.ColumnFixName_FID))
            {
                excelTable.Columns.Add(App.ColumnFixName_FID, typeof (int));
            }

            //添加字段2:表必需要有一个接收人名称字符串字段
            if (!excelTable.Columns.Contains(App.ColumnFixName_FEmployeeAllName))
            {
                excelTable.Columns.Add(App.ColumnFixName_FEmployeeAllName, typeof (string));
            }

            //填充新增字段数据
            int rowcount = excelTable.Rows.Count;
            for (int idx = 0; idx < rowcount; idx++)
            {
                //唯一列
                excelTable.Rows[idx][App.ColumnFixName_FID] = (idx + 1);

                //接收人
                string cnname = excelTable.Rows[idx][App.ColumnName_Import_CnName].ToString();
                string enname = excelTable.Rows[idx][App.ColumnName_Import_EnName].ToString();
                string number = excelTable.Rows[idx][App.ColumnName_Import_JobNumber].ToString();
                excelTable.Rows[idx][App.ColumnFixName_FEmployeeAllName] = string.Format("{0}{1}{2}", cnname, enname, number);
            } //for

            //
        }

        #endregion

        #region 2.GetExportDirectory获取导出文件所在目录

        /// <summary>
        /// 2.已导出文件所在目录
        /// </summary>
        /// <returns></returns>
        public string GetExportDirectory()
        {
            if (_exportSuccess)
            {
                return _exportPath;
            }
            return null;
        }

        private bool _exportSuccess = false;
        private string _exportPath = null;

        #endregion

        #region 3.NextClick事件订阅

        /// <summary>
        /// 3.下一步
        /// </summary>
        public event EventHandler NextClick;

        #endregion

        #endregion

        #region 业务操作方法

        /// <summary>
        /// 1.预览,当前选中行
        /// </summary>
        private void Rp_PreviewCurrentRowCloneReport()
        {
            //数据
            if (m_table == null)
            {
                MessageBox.Show("没有数据", Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //报表模板
            string frx_fullpathname, message;
            bool ok = GetFrxFileFullPathName(out frx_fullpathname,out message);
            if (!ok)
            {
                MessageBox.Show(message, Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //哪一条记录
            m_report_view.Clear();//释放之前加载的报表对象和预览控件
            DataRowView drv = (DataRowView)LbDataRow.SelectedItem;//预览报表
            int fid = (int)drv.Row[App.ColumnFixName_FID];

            #region 读取第几行
            if (m_table_clone_one == null)
            {
                m_table_clone_one = m_table.Clone(); //复制表结构
            }
            else
            {
                m_table_clone_one.Rows.Clear(); //清除原数据
            }
            DataRow[] drss = m_table.Select(string.Format("{0}={1}", App.ColumnFixName_FID, fid));
            foreach (DataRow row in drss)
            {
                m_table_clone_one.ImportRow(row);
            }
            #endregion

            try
            {
                // 加载报表模板文件
                m_report.Load(frx_fullpathname);

                // 注册数据源
                m_report.RegisterData(m_table_clone_one, "Data");

                // 获取报表数据源
                var dataSource = m_report.GetDataSource("Data");
                dataSource.Enabled = true; //启用报表数据源
                m_report.SetParameterValue("Data", dataSource);// 绑定数据源和报表对象

                // 将报表预览控件添加到窗体中
                m_report.Preview = m_report_view;

                // 加载报表数据并刷新预览
                m_report.Prepare();
                m_report.ShowPrepared();
            }
            catch(Exception ex)
            {
                LogFile.Instance().LogException(ex);

                string ex_msg = string.Format("{0}\n\n{1}", ex.GetType().FullName, ex.Message);
                MessageBox.Show(ex_msg, "加载报表模板预览时出错", MessageBoxButtons.OK,MessageBoxIcon.Error);
            }            
        }

        /// <summary>
        /// 2.导出,当前选中行
        /// </summary>
        private void Rp_ExportCurrentRow()
        {
            //数据
            if (m_table == null)
            {
                MessageBox.Show("数据为空", Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //报表
            if (m_report == null)
            {
                MessageBox.Show("报表为空", Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            // 导出文件待保存路径名称
            string fileName = null;
            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "jpg图片文件|*.jpg";

                DataRowView drv = (DataRowView) LbDataRow.SelectedItem;
                string save_name = drv.Row[App.ColumnFixName_FEmployeeAllName].ToString();
                saveFileDialog.FileName = save_name;
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    fileName = saveFileDialog.FileName;
                }
            } //using
            if (string.IsNullOrEmpty(fileName))
            {
                return;
            }

            //导出类型
            bool exportOk = false;
            ExportBase export = null;
            if (fileName.EndsWith(".pdf", true, CultureInfo.InvariantCulture))
            {
                export = new PDFExport();
            }
            else if (fileName.EndsWith(".xlsx", true, CultureInfo.InvariantCulture))
            {
                export = new Excel2007Export();
            }
            else if (fileName.EndsWith(".jpg", true, CultureInfo.InvariantCulture))
            {
                ImageExport exportImg = new ImageExport();
                exportImg.ImageFormat = ImageExportFormat.Jpeg;
                export = exportImg;
            }

            //导出
            if (export != null)
            {
                m_report.Prepare();
                m_report.Export(export, fileName);
                exportOk = true;
                //full_save_name = fileName;
            }

            //
            if (exportOk && File.Exists(fileName))
            {
                if (DialogResult.Yes ==
                    MessageBox.Show("导出完成，是否使用关联应用打开？", Title, MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk))
                {
                    System.Diagnostics.Process.Start(fileName);
                }
            }
        }

        /// <summary>
        /// 3.批量导出(其中一行)
        /// </summary>
        private bool Rp_ExportBatch_ByRow(DataTable table, int rowIdx, string frxPathname,string path)
        {
            if (rowIdx >= table.Rows.Count || rowIdx < 0)
            {
                return false;
            }

            #region 克隆复制表的一行数据
            if (m_table_clone_one == null)
            {
                m_table_clone_one = table.Clone(); //复制表结构
            }
            else
            {
                m_table_clone_one.Rows.Clear(); //清除原数据
            }

            DataRow row = table.Rows[rowIdx];
            m_table_clone_one.ImportRow(row);
            string save_name = string.Format(
                "第{0}行_{1}.jpg",
                (rowIdx+1).ToString().PadLeft(3,'0'),
                row[App.ColumnFixName_FEmployeeAllName]
                );
            #endregion
            
            string file_path_name = Path.Combine(path, save_name);

            // 加载报表模板文件(可选)
            m_report.Load(frxPathname);

            // 注册数据源
            m_report.RegisterData(m_table_clone_one, "Data");

            // 获取报表数据源
            var dataSource = m_report.GetDataSource("Data");
            dataSource.Enabled = true; //启用报表数据源
            m_report.SetParameterValue("Data", dataSource); // 绑定数据源和报表对象

            // 导出报表
            ExportBase export = null; //抽象父类
            ImageExport exportImg = new ImageExport();
            exportImg.ImageFormat = ImageExportFormat.Jpeg;
            export = exportImg;

            //导出
            m_report.Prepare();
            m_report.Export(export, file_path_name);
            return true;
        }

        /// <summary>
        /// 3.批量导出
        /// </summary>
        private void Rp_ExportBatch()
        {
            //报表模板文件
            string frx_fullpathname, message;
            bool ok3 = GetFrxFileFullPathName(out frx_fullpathname, out message);
            if (!ok3)
            {
                MessageBox.Show(message, Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //数据表
            if (m_table == null)
            {
                MessageBox.Show("没有数据", Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //导出保存目录
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                App.TEXT_FolderName_Receiver + DateTime.Today.ToString("yyyyMMdd"));
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            _exportPath = path;

            //
            int rowCount = m_table.Rows.Count;
            int okCount = 0;
            for (int idx = 0; idx < rowCount; idx++)
            {
                bool ok = Rp_ExportBatch_ByRow(m_table, idx, frx_fullpathname, _exportPath);
                okCount += ok ? 1 : 0;
            }

            //
            _exportSuccess = okCount > 0;
            bool fullSuccess = (okCount > 0) && (okCount == rowCount);
            MessageBoxIcon icon = _exportSuccess
                ? (fullSuccess ? MessageBoxIcon.Information : MessageBoxIcon.Exclamation)
                : MessageBoxIcon.Error;
            string msg_success = _exportSuccess
                ? (fullSuccess ? "完成" : "部分完成")
                : "失败";
            string msg = string.Format("{0}，数据表共{1}行，导出{2}个文件。", msg_success, rowCount, okCount);
            MessageBox.Show(msg, Title, MessageBoxButtons.OK, icon);

            //
            if (_exportSuccess)
            {
                if (DialogResult.Yes ==
                    MessageBox.Show("是否打开文件导出目录", Title, MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk))
                {
                    System.Diagnostics.Process.Start(_exportPath);
                }
            }
        }

        /// <summary>
        /// 4.设计
        /// </summary>
        private void Rp_Design()
        {
            //数据
            if (m_table == null)
            {
                MessageBox.Show("没有数据", Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            //模板文件
            string frx_fullpathname ,message;
            bool ok = GetFrxFileFullPathName(out frx_fullpathname, out message);
            if (!ok)
            {
                MessageBox.Show(message, Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            try
            {
                // 加载报表模板文件(可选)
                m_report.Load(frx_fullpathname);

                // 注册数据源
                m_report.RegisterData(m_table, "Data");

                // 将数据源与报表绑定
                m_report.GetDataSource("Data").Enabled = true;

                BtnDesign.Enabled = false; //按钮提示

                m_report.Design();
            }
            catch (Exception ex)
            {
                LogFile.Instance().LogException(ex);

                string ex_msg = string.Format("{0}\n\n{1}", ex.GetType().FullName, ex.Message);
                MessageBox.Show(ex_msg, "设计报表模板时出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                BtnDesign.Enabled = true;//按钮提示
            }
        }

        #endregion

        #region 按钮事件

        /// <summary>
        /// 预览按钮
        /// </summary>        
        private void BtnPreview_Click(object sender, EventArgs e)
        {
            Rp_PreviewCurrentRowCloneReport();//预览按钮
        }

        /// <summary>
        /// 列表选中行变化事件
        /// </summary>
        private void LbDataRow_SelectedIndexChanged(object sender, EventArgs e)
        {
            Rp_PreviewCurrentRowCloneReport();//列表选中行变化事件
        }

        /// <summary>
        /// 导出图片按钮
        /// </summary>        
        private void BtnExport_Click(object sender, EventArgs e)
        {
            Rp_ExportCurrentRow();//导出图片按钮
        }

        /// <summary>
        /// 设计按钮
        /// </summary>        
        private void BtnDesign_Click(object sender, EventArgs e)
        {
            Rp_Design();//设计按钮
        }

        /// <summary>
        /// 批量导出按钮
        /// </summary>
        private void BtnExportBatch_Click(object sender, EventArgs e)
        {
            Rp_ExportBatch();//批量导出按钮
        }

        #endregion

    }
}
